/**
* @name HiveMaps
* @version 0.9.2
* @author Joe Johnston <joe@socialhive.org>
* @copyright (c) 2009 Joe Johnston
* http://socialhive.org/hivemaps
* http://code.google.com/p/hivemaps
*
* Creates SOCIALHIVE.geo.geonames
*
* JavaScript framework for retrieving data from GeoNames <http://www.geonames.org>
*
**/

/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

(function($){
	// functions available in SOCIALHIVE.geo.geonames
  var GeoNames = {
    query: query,
		getHierarchy: getHierarchy,
		getNearestResult: getNearestResult,
		createCityPlace: createCityPlace,
		places: {
			'earth': {"fcodeName":"", "countryName":"", "fcl":"L", "fclName":"parks,area, ...", "name":"Globe", "lng":0, "fcode":"", "geonameId":6295630, "lat":0, "adminName1":"", "population":0},
			'__tpl': {"name":"", "fcodeName":"", "countryName":"", "fcl":"", "fclName":"", "lng":0, "fcode":"", "geonameId":0, "lat":0, "adminCode1":"", "adminName1":"", "countryCode":"", "countryName":"", "population":0}
		}
  };

	var baseURL = 'http://ws.geonames.org/';
	var globalCallbackName = '__GEONAMES_callback_';

	function createScript(url, callback) {
		var script = SOCIALHIVE.utils.loadScript('', false);
		script.url = url+'&callback='+globalCallbackName+script.id;
		// wrap callback so script can be deleted from the page
		window[globalCallbackName+script.id] = function(){
			script.remove();
			callback.apply(callback, arguments);
			setTimeout(function(){delete window[globalCallbackName+script.id];}, 0);
		};
		script.attach();
		return script;
	}
	
	function createCityPlace(name) {
		return $.extend(GeoNames.places.__tpl, {"name":name, "fcl":"PPL", "fclName":"city, village, ..."});
	}
	
	function query(query, callback, country_code, maxRows, featureClass) {
		if (typeof callback !== 'function')
			return false;
		if (!maxRows)
			maxRows = 10;
		if (!featureClass)
			featureClass = 'P';
		var url = baseURL+'searchJSON?q='+escape(query)+(country_code?'&country='+escape(country_code):'')+'&maxRows='+parseInt(maxRows)+'&featureClass='+escape(featureClass);
		createScript(url, callback);
	}
	
	function getNearestResult(results, lat, lon) {
		var nearest = {distance: 999999999, result: null};
		for (var i=0; i<results.geonames.length; i++) {
			var d = SOCIALHIVE.geo.utils.distance(results.geonames[i].lat, results.geonames[i].lng, lat, lon);
			if (d < nearest.distance) {
				nearest.distance = d;
				nearest.result = results.geonames[i];
			}
		}
		return nearest;
	}
	
	function getHierarchy(geoid, callback) {
		if (typeof callback !== 'function')
			return false;
		var url = baseURL+'hierarchyJSON?geonameId='+parseInt(geoid);
		createScript(url, callback);		
	}
	
  if (!window.SOCIALHIVE)
    window.SOCIALHIVE = {};
	if (!window.SOCIALHIVE.geo)
    window.SOCIALHIVE.geo = {};
  window.SOCIALHIVE.geo.geonames = GeoNames;
})(jQuery);